home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / libs / sphigs / sphigs.lha / SPHIGS / examples / robot_anim.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-11-26  |  16.8 KB  |  639 lines

  1. /**************\
  2.               * 
  3.  Program      * Robot
  4.               * Atul Butte
  5.               *
  6.               * This program animates a little robot on the screen.
  7.               *
  8.              /*******************************************************************/
  9.  
  10. /**************\
  11.               * 
  12.  Includes     *
  13.               *
  14.              /*******************************************************************/
  15.  
  16. #include "sphigs.h"
  17.  
  18. /* robot.h   Atul Butte cs123044 */
  19.  
  20. #define MOVE_STEPS        4
  21.  
  22. #define NULL_OBJECT         0
  23. #define STANDARD_BOX         1
  24. #define STANDARD_CUBE         2
  25. #define OUR_ARM             3
  26. #define OUR_ARM_DRAW_ROD     4
  27. #define OUR_ARM_ROTATE_L_THUMB     5
  28. #define OUR_ARM_ROTATE_R_THUMB     6
  29. #define OUR_BODY         7
  30. #define OUR_BODY_ROTATE_ARM     8
  31. #define OUR_ROD             9
  32. #define OUR_ROOM        10
  33. #define OUR_ROOM_ROTATE_ROBOT    11
  34. #define OUR_ROOM_MOVE_ROBOT    12
  35. #define OUR_ROOM_DRAW_ROD    13
  36.  
  37. enum direction { NORTH, SOUTH, EAST, WEST };
  38.  
  39.  
  40.  
  41. #include <stdio.h>
  42. #include <assert.h>
  43. #include <math.h>
  44.  
  45. /**************\
  46.               * 
  47.  Defines      *
  48.               *
  49.              /*******************************************************************/
  50.  
  51. typedef enum { false, true } Boolean;
  52. #define WaitForKeystroke        SRGP_waitEvent(-1)
  53.  
  54.  
  55. /**************\
  56.               * 
  57.  Data         *
  58.               *
  59.              /*******************************************************************/
  60.  
  61. /* verticies for room */
  62.  
  63. static point room_vertices[] = {
  64.     { -50., -50., -50. },
  65.     { 50., -50., -50. },
  66.     { -50., 50., -50. },
  67.     { -50., -50., 50. },
  68.     { 50., 50., -50. },
  69.     { 50., -50., 50. },
  70.     { -50., 50., 50. },
  71.     { 50., 50., 50. }
  72. };
  73.  
  74. /* facets for room */
  75.  
  76. static vertex_index room_facets[] = {
  77.      0,1,4,2, -1,
  78.      2,4,7,6,-1,
  79.      6,7,5,3,-1,
  80.      3,5,1,0, -1,
  81.      3,0,2,6,-1,
  82.     1,5,7,4, -1
  83. };
  84.  
  85. /* verticies for arm */
  86.  
  87. static point arm_vertices[] = {
  88.     { -2.5, 0., -2.5 },
  89.     { 2.5, 0., -2.5 },
  90.     { -2.5, 20., -2.5 },
  91.     { -2.5, 0, 2.5 },
  92.     { 2.5, 20., -2.5 },
  93.     { 2.5, 0., 2.5 },
  94.     { -2.5, 20., 2.5 },
  95.     { 2.5, 20., 2.5 }
  96. };
  97.  
  98. /* facets for arm */
  99.  
  100. static vertex_index arm_facets[] = {
  101.   0,1,4,2, -1,
  102.   2,4,7,6, -1,
  103.   6,7,5,3, -1,
  104.   3,5,1,0, -1,
  105.   3,0,2,6, -1,
  106.   1,5,7,4, -1
  107. };
  108.  
  109.  
  110.  
  111. /* READS three doubles from stdin */
  112. ReadVector (vec)
  113. double *vec;
  114. {
  115.    scanf("%lf %lf %lf\n", &vec[0], &vec[1], &vec[2]);
  116. }
  117.  
  118. CreateNormalizedRoomStructure()
  119. {
  120.    int i;
  121.  
  122.    SPH_openStructure (STANDARD_BOX);
  123.    SPH_polyhedron (8,6, room_vertices, room_facets);
  124.    SPH_closeStructure();
  125. }
  126.  
  127. CreateNormalizedArmStructure()
  128. {
  129.    int i;
  130.  
  131.    SPH_openStructure (STANDARD_CUBE);
  132.    SPH_polyhedron (8,6, arm_vertices, arm_facets);
  133.    SPH_closeStructure();
  134. }
  135.  
  136. #define WaitForKeystroke    SRGP_waitEvent(-1)
  137. #define WriteMessage(s)      SRGP_text (SRGP_defPoint(15,4), s)
  138. #define WriteUpperMessage(s)      SRGP_text (SRGP_defPoint(15,20), s)
  139.  
  140. /**************\
  141.               * 
  142.  Procedure    * main( )
  143.               *
  144.               * Mainline. Initializes SPHIGS, sets up the camera angle,
  145.               * defines the animated objects, and animates them.
  146.               *
  147.              /*******************************************************************/
  148.  
  149. main(argc, argv )
  150. int argc;
  151. char **argv;
  152. {
  153.    matrix vo_matrix, vm_matrix;
  154.    matrix temp_matrix;
  155.  
  156.    /* VIEW 0 INITIALLY: */
  157.    point vrp, prp;
  158.    double umin, umax, vmin, vmax;
  159.    double fplane, bplane;
  160.    vector vpn, vupv;
  161.  
  162.    int i;
  163.  
  164.    fprintf (stderr, "I hope you redirected stdin...\n");
  165.  
  166.    ReadVector (vrp);
  167.    ReadVector (vpn);
  168.    ReadVector (vupv);
  169.    ReadVector (prp);
  170.    scanf ("%lf %lf\n", &fplane, &bplane);
  171.    scanf ("%lf %lf   %lf %lf\n", &umin, &umax, &vmin, &vmax);
  172.  
  173.    SPH_begin (500, 500, 1, 0);
  174.  
  175.    SPH_setDoubleBufferingFlag (TRUE);
  176.  
  177.  
  178.    SPH_evaluateViewOrientationMatrix 
  179.       (vrp,
  180.        vpn,
  181.        vupv,
  182.        vo_matrix);
  183.  
  184.    SPH_evaluateViewMappingMatrix
  185.       (umin, umax,   vmin, vmax, PERSPECTIVE,
  186.        prp,
  187.        fplane, bplane,
  188.        0.0,1.0, 0.0,1.0, 0.0,1.0,
  189.        vm_matrix);
  190.  
  191.    SPH_setViewRepresentation
  192.       (0,
  193.        vo_matrix, vm_matrix,
  194.        0.0, 1.0,  0.0,1.0,  0.0,1.0);
  195.  
  196.  
  197.    SPH_setViewPointLightSource (0,   0.0, 100.0, 150.0);
  198.  
  199.    SPH_loadCommonColor (2, "yellow");
  200.    SPH_loadCommonColor (3, "green");
  201.    SPH_loadCommonColor (4, "turquoise");
  202.    SPH_loadCommonColor (5, "pink");
  203.    SPH_loadCommonColor (6, "goldenrod");
  204.    SPH_loadCommonColor (7, "beige");
  205.  
  206.    SPH_setRenderingMode (0, WIREFRAME_RAW); 
  207.  
  208. /*    set_up_camera( ); */
  209.     define_structures( );
  210.     animate( );
  211.     SPH_end( );
  212. }
  213.  
  214. /**************\
  215.               * 
  216.  Procedure    * set_up_camera( )
  217.               *
  218.               * Initializes the SPHIGS camera angle and position.
  219.               *
  220.              /*******************************************************************/
  221.  
  222. set_up_camera( )
  223. {
  224.     point    view_ref_point;                /* view reference point */
  225.     vector    view_plane_normal;            /* view plane normal */
  226.     vector    view_up_vector;                /* view up vector */
  227.     matrix    vo_matrix;                /* view orientation matrix */
  228.     
  229.     double    umin, umax, vmin, vmax;            /* max/min VRC size */
  230.     point    proj_ref_point;                /* projection reference point */
  231.     double    proj_viewport_minx, proj_viewport_maxx;    /* max/min viewport size */
  232.     double    proj_viewport_miny, proj_viewport_maxy;    /* max/min viewport size */
  233.     matrix    vm_matrix;                /* view mapping matrix */
  234.     
  235.     view_ref_point[0] = 0.0;
  236.     view_ref_point[1] = 0.0;
  237.     view_ref_point[2] = 0.0;
  238.     
  239.     view_plane_normal[0] = 0.0;
  240.     view_plane_normal[1] = 0.0;
  241.     view_plane_normal[2] = 1.0;
  242.     
  243.     view_up_vector[0] = 0.0;
  244.     view_up_vector[1] = 1.0;
  245.     view_up_vector[2] = 0.0;
  246.     
  247.     SPH_evaluateViewOrientationMatrix( view_ref_point, view_plane_normal, view_up_vector, vo_matrix );
  248.  
  249.  
  250.     proj_ref_point[0] = 20.0;
  251.     proj_ref_point[1] = 30.0;
  252.     proj_ref_point[2] = -120.0;
  253.     
  254.     umin = -120.0;
  255.     umax = 120.0;
  256.     vmin = -120.0;
  257.     vmax = 120.0;
  258.     
  259.     proj_viewport_minx = 0.0;
  260.     proj_viewport_maxx = 1.0;
  261.     proj_viewport_miny = 0.0;
  262.     proj_viewport_maxy = 1.0;
  263.     
  264.     SPH_evaluateViewMappingMatrix 
  265.        (umin, umax, vmin, vmax, PERSPECTIVE, 
  266.     proj_ref_point, 
  267.     -0.001, -99999999.0,
  268.     proj_viewport_minx, proj_viewport_maxx, 
  269.     proj_viewport_miny, proj_viewport_maxy, 
  270.     0.0, 1.0,
  271.     vm_matrix);
  272.     
  273.     SPH_setViewRepresentation
  274.        (0, vo_matrix, vm_matrix, 0.0,1.0, 0.0,1.0, 0.0,1.0);
  275. }
  276.  
  277. /**************\
  278.               * 
  279.  Procedure    * define_structures( )
  280.               *
  281.               * This routine constructs all the objects. These objects include
  282.               * the standard box (center in middle), the standard cube (center
  283.               * at middle of bottom facet), the rod, the robot arm, the robot
  284.               * body, and the entire room.
  285.               * 
  286.               * These objects are obvious constructed with knowledge on how
  287.               * they are going to be manipulated in the animation (e.g. space
  288.               * is made for the rod in the hand, etc).
  289.               *
  290.              /*******************************************************************/
  291.  
  292. define_structures( )
  293. {
  294.     int            i;            /* index through facets */
  295.     matrix        temp_matrix;            /* transformation matrix */
  296.     
  297. /* Create NULL_OBJECT */
  298.     
  299.     SPH_openStructure( NULL_OBJECT );
  300.     SPH_closeStructure( );
  301.     
  302. /* Create STANDARD_BOX */
  303.     
  304.     CreateNormalizedRoomStructure();
  305.  
  306. /* Create STANDARD_CUBE */
  307.  
  308.     CreateNormalizedArmStructure();
  309.    
  310. /* Create OUR_ROD */
  311.     
  312.     SPH_openStructure( OUR_ROD );
  313.     SPH_setModXform (SPH_scale(1./50., 4./10., 1./50., temp_matrix), ASSIGN);
  314.     SPH_executeStructure( STANDARD_BOX );
  315.     SPH_closeStructure( );
  316.     
  317. /* Create OUR_ARM */
  318.     
  319.     SPH_openStructure( OUR_ARM );
  320.     SPH_executeStructure( STANDARD_CUBE );
  321.     
  322.     /* left thumb */
  323.     SPH_label( OUR_ARM_ROTATE_L_THUMB );
  324.     SPH_setModXform( SPH_rotateZ( 90.0, temp_matrix ), ASSIGN );
  325.     SPH_setModXform( SPH_scale( 1./5., 1./4., 1./5., temp_matrix), PRECONCATENATE );
  326.     SPH_setModXform( SPH_translate( -1., 20., 0., temp_matrix), PRECONCATENATE );
  327.     SPH_executeStructure( STANDARD_CUBE );
  328.     
  329.     /* right thumb */
  330.     SPH_label( OUR_ARM_ROTATE_R_THUMB );
  331.     SPH_setModXform( SPH_rotateZ( -90.0, temp_matrix ), ASSIGN );
  332.     SPH_setModXform( SPH_scale( 1./5., 1./4., 1./5., temp_matrix ), PRECONCATENATE );
  333.     SPH_setModXform( SPH_translate( 1., 20., 0., temp_matrix ), PRECONCATENATE );
  334.     SPH_executeStructure( STANDARD_CUBE );
  335.     
  336.     /* space for rod */
  337.     SPH_setModXform( SPH_rotateX( -90., temp_matrix ), ASSIGN );
  338.     SPH_setModXform( SPH_translate( 0., 23., 0., temp_matrix ), PRECONCATENATE );
  339.     SPH_setModXform( SPH_translate( 0., 0., -10., temp_matrix ), PRECONCATENATE );
  340.     SPH_label( OUR_ARM_DRAW_ROD );
  341.     SPH_executeStructure( NULL_OBJECT );
  342.  
  343.     SPH_closeStructure( );
  344.     
  345. /* Create OUR_BODY */
  346.     
  347.     SPH_openStructure( OUR_BODY );
  348.     
  349.     /* arm */
  350.     SPH_label( OUR_BODY_ROTATE_ARM );
  351.     SPH_setModXform( SPH_rotateX( 0.0, temp_matrix ), ASSIGN );
  352.     SPH_setModXform( SPH_translate( 0., -30., 0., temp_matrix ), PRECONCATENATE );
  353.     SPH_executeStructure( OUR_ARM );
  354.     
  355.     /* torso */
  356.     SPH_setModXform( SPH_scale( 1.0/10.0, 1.0/5.0, 1.0/10.0, temp_matrix ), ASSIGN );
  357.     SPH_setModXform( SPH_translate( 0., -40., 0., temp_matrix ), PRECONCATENATE );
  358.     SPH_executeStructure( STANDARD_BOX );
  359.     
  360.     SPH_closeStructure( );
  361.  
  362. /* Create OUR_ROOM */
  363.     
  364.     SPH_openStructure( OUR_ROOM );
  365.     
  366.     /* draw boundaries of room */
  367.     SPH_executeStructure( STANDARD_BOX );
  368.     
  369.     /* draw body */
  370.     SPH_label( OUR_ROOM_ROTATE_ROBOT );
  371.     SPH_setModXform( SPH_rotateY( 0.0, temp_matrix ), ASSIGN );
  372.     SPH_label( OUR_ROOM_MOVE_ROBOT );
  373.     SPH_setModXform( SPH_translate( 0., 0., 0., temp_matrix ), PRECONCATENATE );
  374.     SPH_executeStructure( OUR_BODY );
  375.     
  376.     /* draw rod */
  377.     SPH_setModXform( SPH_rotateY( 0.0, temp_matrix ), ASSIGN );
  378.     SPH_setModXform( SPH_translate( 0., -20., -40., temp_matrix ), PRECONCATENATE );
  379.     SPH_label( OUR_ROOM_DRAW_ROD );
  380.     SPH_executeStructure( OUR_ROD );
  381.     
  382.     SPH_closeStructure( );
  383. }
  384.  
  385. /**************\
  386.               * 
  387.  Procedure    * spinrobot( direction dir, Boolean ccw )
  388.               *
  389.               * Rotates the robot to the given direction with the given path
  390.               * (i.e. clockwise or counterclockwise).
  391.               *
  392.              /*******************************************************************/
  393.  
  394. spinrobot( dir, ccw )
  395. enum direction            dir;            /* final direction */
  396. Boolean                ccw;            /* path */
  397. {
  398.     matrix            temp_matrix;        /* transformation matrix */
  399.     static double        prev_dir = 0.0;        /* previous direction */
  400.     double            rot_angle;        /* intermediate rotation angle */
  401.     double            end_angle;        /* final angle */
  402.     
  403.     switch( dir ) {
  404.       case NORTH:
  405.     if( ccw )
  406.         end_angle = 0.0;
  407.     else
  408.         end_angle = 360.0;
  409.     break;
  410.       case WEST:
  411.     end_angle = 270.0;
  412.     break;
  413.       case SOUTH:
  414.     end_angle = 180.0;
  415.     break;
  416.       case EAST:
  417.     end_angle = 90.0;
  418.     break;
  419.     }
  420.     
  421.     if( prev_dir == 0.0 || prev_dir == 360.0 )
  422.     prev_dir = ( ccw ) ? 360.0 : 0.0;
  423.     
  424.     rot_angle = ( end_angle - prev_dir ) / 2.0  + prev_dir;
  425.     
  426.     /* Draw intermediate angle */
  427.     
  428.     SPH_openStructure( OUR_ROOM );
  429.     SPH_setElementPointer( 0 );
  430.     SPH_moveElementPointerToLabel( OUR_ROOM_ROTATE_ROBOT );
  431.     SPH_offsetElementPointer( 1 );
  432.     SPH_deleteElement( );
  433.     SPH_setModXform( SPH_rotateY( rot_angle, temp_matrix ), ASSIGN );
  434.     SPH_closeStructure( );
  435.     
  436.     /* Draw final angle */
  437.     
  438.     SPH_openStructure( OUR_ROOM );
  439.     SPH_setElementPointer( 0 );
  440.     SPH_moveElementPointerToLabel( OUR_ROOM_ROTATE_ROBOT );
  441.     SPH_offsetElementPointer( 1 );
  442.     SPH_deleteElement( );
  443.     SPH_setModXform( SPH_rotateY( end_angle, temp_matrix ), ASSIGN );
  444.     SPH_closeStructure( );
  445.     
  446.     prev_dir = end_angle;
  447. }
  448.  
  449. /**************\
  450.               * 
  451.  Procedure    * lowerarm( )
  452.               *
  453.               * Gradually lowers the arm of the robot.
  454.               *
  455.              /*******************************************************************/
  456.  
  457. lowerarm( )
  458. {
  459.     matrix    temp_matrix;        /* transformation matrix */
  460.     double    i;            /* index through angles */
  461.     
  462.     for( i = 45.0; i <= 90.0; i += 45.0 ) {
  463.     SPH_openStructure( OUR_BODY );
  464.     SPH_setElementPointer( 0 );
  465.     SPH_moveElementPointerToLabel( OUR_BODY_ROTATE_ARM );
  466.     SPH_offsetElementPointer( 1 );
  467.     SPH_deleteElement( );
  468.     SPH_setModXform( SPH_rotateX( i, temp_matrix ), ASSIGN );
  469.     SPH_closeStructure( );
  470.     }
  471. }
  472.  
  473. /**************\
  474.               * 
  475.  Procedure    * raisearm( )
  476.               *
  477.               * Gradually raises the arm of the robot.
  478.               *
  479.              /*******************************************************************/
  480.  
  481. raisearm( )
  482. {
  483.     matrix    temp_matrix;        /* transformation matrix */
  484.     double    i;            /* index through angles */
  485.     
  486.     for( i = 45.0; i >= 0.0; i -= 45.0 ) {
  487.     SPH_openStructure( OUR_BODY );
  488.     SPH_setElementPointer( 0 );
  489.     SPH_moveElementPointerToLabel( OUR_BODY_ROTATE_ARM );
  490.     SPH_offsetElementPointer( 1 );
  491.     SPH_deleteElement( );
  492.     SPH_setModXform( SPH_rotateX( i, temp_matrix ), ASSIGN );
  493.     SPH_closeStructure( );
  494.     }
  495. }
  496.  
  497. /**************\
  498.               * 
  499.  Procedure    * grab( )
  500.               *
  501.               * Grips the fingers together.
  502.               *
  503.              /*******************************************************************/
  504.  
  505. grab( )
  506. {
  507.     matrix    temp_matrix;        /* transformation matrix */
  508.     double    i, j;            /* index through angles */
  509.  
  510.     for( i = 45.0, j = -45.0; i >= 0.0; i -= 45.0, j += 45.0 ) {
  511.     SPH_openStructure( OUR_ARM );
  512.     SPH_setElementPointer( 0 );
  513.     SPH_moveElementPointerToLabel( OUR_ARM_ROTATE_L_THUMB );
  514.     SPH_offsetElementPointer( 1 );
  515.     SPH_deleteElement( );
  516.     SPH_setModXform( SPH_rotateZ( i, temp_matrix ), ASSIGN );
  517.     
  518.     SPH_moveElementPointerToLabel( OUR_ARM_ROTATE_R_THUMB );
  519.     SPH_offsetElementPointer( 1 );
  520.     SPH_deleteElement( );
  521.     SPH_setModXform( SPH_rotateZ( j, temp_matrix ), ASSIGN );
  522.     SPH_closeStructure( );
  523.     }
  524. }
  525.  
  526. /**************\
  527.               * 
  528.  Procedure    * pickup( )
  529.               *
  530.               * Erases the rod from the room and adds it to the hand (arm) of
  531.               * the robot.
  532.               *
  533.              /*******************************************************************/
  534.  
  535. pickup( )
  536. {
  537.     matrix    temp_matrix;            /* transformation matrix */
  538.  
  539.     SPH_openStructure( OUR_ROOM );
  540.     SPH_setElementPointer( 0 );
  541.     SPH_moveElementPointerToLabel( OUR_ROOM_DRAW_ROD );
  542.     SPH_offsetElementPointer( 1 );
  543.     SPH_deleteElement( );
  544.     SPH_executeStructure( NULL_OBJECT );
  545.     SPH_closeStructure( );
  546.  
  547.     SPH_openStructure( OUR_ARM );
  548.     SPH_setElementPointer( 0 );
  549.     SPH_moveElementPointerToLabel( OUR_ARM_DRAW_ROD );
  550.     SPH_offsetElementPointer( 1 );
  551.     SPH_deleteElement( );
  552.     SPH_executeStructure( OUR_ROD );
  553.     SPH_closeStructure( );
  554. }
  555.  
  556. /**************\
  557.               * 
  558.  Procedure    * moveto( double x, double z )
  559.               *
  560.               * Gradually moves the robot to the (x,z) coordinate in the room.
  561.               *
  562.              /*******************************************************************/
  563.  
  564. moveto( x, z )
  565. double        x;            /* final x coordinate */
  566. double        z;            /* final z coordinate */
  567. {
  568.     static double    prev_x = 0.0;                /* previous x coordinate */
  569.     static double    prev_z = 0.0;                /* previous z coordinate */
  570.     double        x_step = (x - prev_x) / MOVE_STEPS;    /* x step value */
  571.     double        z_step = (z - prev_z) / MOVE_STEPS;    /* z step value */
  572.     double        curr_x = prev_x + x_step;        /* current x coordinate in loop */
  573.     double        curr_z = prev_z + z_step;        /* current z coordinate in loop */
  574.     matrix        temp_matrix;                /* transformation matrix */
  575.     int            i;                    /* index through angles */
  576.     
  577.     for( i = 0; i < MOVE_STEPS; i++ ) {
  578.     SPH_openStructure( OUR_ROOM );
  579.     SPH_setElementPointer( 0 );
  580.     SPH_moveElementPointerToLabel( OUR_ROOM_MOVE_ROBOT );
  581.     SPH_offsetElementPointer( 1 );
  582.     SPH_deleteElement( );
  583.     SPH_setModXform( SPH_translate( curr_x, 0., curr_z, temp_matrix ), PRECONCATENATE );
  584.     curr_x += x_step;
  585.     curr_z += z_step;
  586.     SPH_closeStructure( );
  587.     }
  588.     prev_x = x;
  589.     prev_z = z;
  590. }
  591.  
  592. /**************\
  593.               * 
  594.  Procedure    * animate( )
  595.               *
  596.               * Animates the robot with a script.
  597.               *
  598.              /*******************************************************************/
  599.  
  600. animate( )
  601. {
  602.     SPH_postRoot( OUR_ROOM, 0 );
  603.     moveto( 0.0, 30.0 );
  604.     spinrobot( EAST, false );
  605.     moveto( 30.0, 30.0 );
  606.     spinrobot( SOUTH, false );
  607.     moveto( 30.0, -40.0 );
  608.     spinrobot( WEST, false );
  609.     moveto( -30.0, -40.0 );
  610.     spinrobot( NORTH, false );
  611.     moveto( -30.0, 30.0 );
  612.     spinrobot( EAST, false );
  613.     moveto( 0.0, 30.0 );
  614.     spinrobot( SOUTH, false );
  615.     moveto( 0.0, -13.0 );
  616.     lowerarm( );
  617.     grab( );
  618.     pickup( );
  619.     raisearm( );
  620.     spinrobot( EAST, true );
  621.     spinrobot( NORTH, true );
  622.     moveto( 0.0, 30.0 );
  623.     spinrobot( WEST, true );
  624.     moveto( -30.0, 30.0 );
  625.     spinrobot( SOUTH, true );
  626.     moveto( -30.0, -30.0 );
  627.     spinrobot( EAST, true );
  628.     moveto( 30.0, -30.0 );
  629.     spinrobot( NORTH, true );
  630.     moveto( 30.0, 30.0 );
  631.     spinrobot( WEST, true );
  632.     moveto( 0.0, 30.0 );
  633.     spinrobot( SOUTH, true );
  634.     lowerarm( );
  635.     raisearm( );
  636.     WaitForKeystroke;
  637. }
  638.  
  639.